# EntityRelation.java

    package org.codefilarete.stalactite.engine.configurer.model;

    import javax.annotation.Nullable;

    import org.codefilarete.reflection.ReadWritePropertyAccessPoint;
    import org.codefilarete.stalactite.dsl.property.CascadeOptions.RelationMode;
    import org.codefilarete.stalactite.sql.ddl.structure.Table;
    import org.codefilarete.stalactite.sql.result.BeanRelationFixer;

    /**
     * Made for
     * - one-to-one,
     * - secondary-table,
     * - mapped-superclass cases.
     *
     * @param <SRC>
     * @param <TRGT>
     * @author Guillaume Mary
     */
    public abstract class EntityRelation<SRC, TRGT, LEFTTABLE extends Table<LEFTTABLE>, RIGHTTABLE extends Table<RIGHTTABLE>, JOINTYPE>
    		extends Relation<SRC, TRGT, LEFTTABLE, RIGHTTABLE, JOINTYPE> {

    	private final Entity<TRGT, ?, RIGHTTABLE> targetEntity;

    	@Nullable
    	private final ReadWritePropertyAccessPoint<TRGT, SRC> mappedByAccessor;

    	private final BeanRelationFixer<SRC, TRGT> beanRelationFixer;

    	public EntityRelation(Entity<TRGT, ?, RIGHTTABLE> targetEntity,
    	                      ReadWritePropertyAccessPoint<SRC, TRGT> accessor,
    						  @Nullable ReadWritePropertyAccessPoint<TRGT, SRC> mappedByAccessor,
    						  RelationMode relationMode,
    						  boolean fetchSeparately,
    						  // JOINTYPE can be either SRC PK or TARGET PK for one-to-one. Can only by SRC PK for secondary-table and mapped-superclass
    						  DirectRelationJoin<LEFTTABLE, RIGHTTABLE, JOINTYPE> join,
    						  BeanRelationFixer<SRC, TRGT> beanRelationFixer) {
    		super(accessor, relationMode, fetchSeparately, join);
    		this.targetEntity = targetEntity;
    		this.mappedByAccessor = mappedByAccessor;
    		this.beanRelationFixer = beanRelationFixer;
    	}

    	public <TRGTID> Entity<TRGT, TRGTID, RIGHTTABLE> getTargetEntity() {
    		return (Entity<TRGT, TRGTID, RIGHTTABLE>) targetEntity;
    	}

    	@Nullable
    	public ReadWritePropertyAccessPoint<TRGT, SRC> getMappedByAccessor() {
    		return mappedByAccessor;
    	}

    	@Override
    	public DirectRelationJoin<LEFTTABLE, RIGHTTABLE, JOINTYPE> getJoin() {
    		return (DirectRelationJoin<LEFTTABLE, RIGHTTABLE, JOINTYPE>) super.getJoin();
    	}

    	@Override
    	public BeanRelationFixer<SRC, TRGT> getRelationFixer() {
    		return beanRelationFixer;
    	}
    }